/***************************************
 * 说明：本文件主要列举课后习题
 * *************************************/
#include <iostream>
#include "test.h"
using namespace std;

/**************************************************
 * 习题2：分析下面的程序，写出其运行的结果
 * ************************************************/
Date::Date(int y, int m, int d)
{
    year = y;
    month = m;
    day = d;
}
Date::Date(int m, int d)
{
    year = 2005;
    month = m;
    day = d;
}
Date::Date(int d)
{
    year = 2005;
    month = 1;
    day = d;
}
Date::Date()
{
    year = 2005;
    month = 1;
    day = 1;
}
void Date::display()
{
    cout << "year= " << year << " month = " << month << " day =" << day << endl;
}
void excerise2()
{
    Date d1(2005, 10,13);
    Date d2(4,16);
    Date d3(12);
    Date d4;
    d1.display();
    d2.display();
    d3.display();
    d4.display();
}
/**************************************************
 * 习题4：建立一个对象数组，内放5个学生的数据（学号/成绩）
 * 用指针指向数组首元素，输出第1/3/5个学生的数据
 * ************************************************/
Student::Student(int n, int s)
{
    num = n;
    score = s;
}
void Student::show_msg()
{
    cout << "num = " << num << " score = " << score << endl;
}
void excerise4()
{
    Student stu1[5] = {
        Student(1, 23),
        Student(2, 34),
        Student(3, 45),
        Student(4, 56),
        Student(5, 67)
    };
    Student* stu = &stu1[0];
    stu->show_msg();
    (stu + 2)->show_msg();
    (stu + 4)->show_msg();
}
/************************************************************
 * 习题5：建立一个对象数组，内放5个学生的数据（学号/成绩）
 * 设立一个max函数，在max函数中找出5个学生中成绩最高者并输出其学号
 * **********************************************************/
void Student::max(Student* stu)
{
    Student result(0, 0);
    int maxScore = 0;
    for(int i = 0; i<5; i++) {
        if (maxScore < stu[i].score) {
            result = stu[i]; // 使用类的赋值操作符
        }
    }
    cout << "max score = " << result.score << "num is " << result.num << endl;
}
void excerise5()
{
    Student stu[5] = {
        Student(1, 23),
        Student(2, 34),
        Student(3, 45),
        Student(4, 56),
        Student(5, 67)
    };
    Student::max(stu);
}
/*******************************
 * 习题6：分析一下程序的运行结果
 * ****************************/
void excerise6()
{
    Student1 stu(1, 78.5);
    stu.display();
    Student1 stu2(2, 80.5);
    stu2.display();
}

/*************************************
 * 习题7：将题6的程序作如下修改，查看效果
 * ***********************************/
void excerise7()
{
    const Student1 stu(1, 78.5);
    stu.change(10, 99.0);
    stu.display();
    Student1 stu2(2, 80.5);
    stu2.display();
}

/*************************************
 * 习题8：将题目6的基础上增加一个func函数，
 * 在func函数中引用change/display函数
 * func中使用类的引用Student&
 * ***********************************/
void Student1::func(const Student1& stu) const
{
    stu.change(10, 23);
    stu.display();
}
void excerise8()
{
    const Student1 stu(1, 4.5);
    stu.func(stu);
}
/*************************************
 * 习题9：商店销售一种统一的商品，商店每天公布折扣，同时允许销售人员销售时灵活掌握售价
 * 在此基础上，对一次购买10件以上的还可以享受98折的优惠，当天3个销售人员的销售情况如下：
 *    销售货号       销售件数       销售单价
 *       101           5             23.5
 *       102           12            24.56
 *       103           100           21.5
 * 计算当日商品的总销售款以及每件的平均售价
 * ***********************************/
Goods::Goods(int n, float p)
{
    num = n;
    price = p;
}
void Goods::comp_sum()
{
    float finalPrice = price;
    if (price > 10) {
        finalPrice = price * 0.98 * (1-discount);
    }
    count = count + num;
    sum = sum + num * finalPrice; 
    cout << "count = " << count << endl;
    cout << "sum = " << sum << endl;
}
void Goods::show_average()
{
    cout << "sum = " << sum << endl;
    cout << "average = " << (sum / count) << endl;
}
int Goods::count = 0;
float Goods::sum = 0;
float Goods::discount = 0.05;
void excerise9()
{
    Goods goods1(5, 23.5);
    goods1.comp_sum();
    Goods goods2(12, 24.56);
    goods2.comp_sum();
    Goods goods3(100, 21.5);
    goods3.comp_sum();
    Goods::show_average();
}
/*******************************************
 * 习题10：声明类Time和Date1，
 * 类外声明display函数，函数输出两个类的私有数据
 * *****************************************/
Date1::Date1(int y, int m, int d)
{
    year = y;
    month = m;
    day = d;
}
Time::Time(int h, int m, int s)
{
    hour = h;
    minute = m;
    second = s;
}
void display(Date1& date, Time& time)
{
    cout << date.year << ":" << date.month << ":" << date.day << ":";
    cout << time.hour << ":" << time.minute << ":" << time.second << endl;
}
void excerise10()
{
    Date1 date(2021, 04, 17);
    Time time(23, 42, 9);
    display(date, time);
}
/*******************************************
 * 习题11：将Time1类声明为Date类的友元类，通过
 * Time1类中的display函数引用date类对象的私有
 * 数据成员，输出年月日时分秒
 * *****************************************/
Time1::Time1(int h, int m, int s)
{
    hour = h;
    minute = m;
    second = s;
}
void excerise11()
{
    Date1 date(2021, 04, 17);
    Time1 time(23, 42, 9);
    time.display(date);
}
/*******************************************
 * 习题12：声明一个类模板，利用它分别实现两个整数
 * 浮点数和字符串的比较，在类模板外实现
 * *****************************************/
template<class numtype>
Compare<numtype>::Compare(numtype n1, numtype n2)
{
    num1 = n1;
    num2 = n2;
}
template<class numtype>
numtype Compare<numtype>::max()
{
    return (num1 > num2) ? num1 :  num2;
}
template<class numtype>
numtype Compare<numtype>::min()
{
    return (num1 < num2) ? num1 : num2;
}
void excerise12()
{
    Compare<int>cmp1(23, 78);
    cout << "cmp1 max = " << cmp1.max() << endl;
    cout << "cmp1 min = " << cmp1.min() << endl;
    Compare<float>cmp2(7.34, 4.26);
    cout << "cmp2 max = " << cmp2.max() << endl;
    cout << "cmp2 min = " << cmp2.min() << endl;
    Compare<char>cmp3('a', 'c');
    cout << "cmp3 max = " << cmp3.max() << endl;
    cout << "cmp3 min = " << cmp3.min() << endl;
}
int main()
{
    excerise12();
}